package tt.dz.egobus.servicemanager.entities;

import org.hibernate.annotations.ColumnDefault;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.NotEmpty;
import tt.dz.egobus.api.managerservice.manager.UserRequestTypeInfo;
import tt.dz.egobus.base.entity.BaseEntity;
import tt.dz.egobus.bean.BusinessStatus;
import tt.dz.egobus.emuns.OrderStatus;

import javax.persistence.*;


/**
 * @author Anson
 * @date 17-3-27
 * @name 业务服务表
 * @since 1.0.3
 */
@Entity
@Table(name = "business_service", schema = "servicemanager")
@NamedQueries(
        value = {
                @NamedQuery(
                        name = "isExitUserUnDoneBusiness",
                        query = " select count(id)  from BusinessService where  userId=:userId and isValidate=true " +
                                "   and ( status = " + BusinessService.BEGIN_BUSINESS_VALUE +
                                "  or status = " + BusinessService.BUSINESS_VALUE + ")    "),
                @NamedQuery(
                        name = "getUserUnDoneService",
                        query = " select service from BusinessService service where  userId=:userId and isValidate=true " +
                                "   and ( status = " + BusinessService.BEGIN_BUSINESS_VALUE +
                                "  or status = " + BusinessService.BUSINESS_VALUE + ")    "),
                @NamedQuery(
                        name = "getDriverUnDoneService",
                        query = " select service  from BusinessService service where  driverId=:driverId and isValidate=true " +
                                "   and ( status = " + BusinessService.BEGIN_BUSINESS_VALUE +
                                "  or status = " + BusinessService.BUSINESS_VALUE + ")    ")
        }
)
public class BusinessService extends BaseEntity {


    private static final long serialVersionUID = -3673203750187031121L;

    /**
     * {@link BusinessStatus#BEGIN_BUSINESS}
     */
    public static final int BEGIN_BUSINESS_VALUE = 20;

    /**
     * {@link BusinessStatus#BUSINESS}
     */
    public static final int BUSINESS_VALUE = 30;


    /**
     * @author Anson
     * @date 17-3-28
     * @name 确信当前是可以接单的状态
     * @since 1.0.3
     */
    public boolean isAbleDoBeginBusiness() {
        return this.assertActive();
    }

    /**
     * @author Anson
     * @date 17-3-28
     * @name 确信当前是可以接单的状态 </br>抢单模式下
     * @since 1.0.3
     */
    public boolean isAbleDoBeginBusinessInGrab() {
        return this.assertGrabBusiness();
    }

    /**
     * 确信当前处于激活状态
     *
     * @return
     */
    public boolean assertActive() {
        return BusinessStatus.assertActive(this.status);
    }

    /**
     * 确信当前处于抢单中状态
     *
     * @return
     */
    public boolean assertGrabBusiness() {
        return BusinessStatus.assertGrabBusiness(this.status);
    }


    /**
     * 确信当前处于开始状态
     *
     * @return
     */
    public boolean assertBeginBusiness() {
        return BusinessStatus.assertBeginBusiness(this.status);
    }

    /**
     * 确信当前处于进行状态
     *
     * @return boolean
     */
    public boolean assertBusiness() {
        return BusinessStatus.assertBusiness(this.status);
    }

    /**
     * 确信当前处于进行状态
     *
     * @return boolean
     */
    public boolean assertFinish() {
        return BusinessStatus.assertFinish(this.status);
    }

    /**
     * 确信当前处于取消状态
     *
     * @return boolean
     */
    public boolean assertCancal() {
        return BusinessStatus.assertCancel(this.status);
    }

    /**
     * 确信当前处于预约成功
     *
     * @return boolean
     */
    public boolean assertBespeakSuccess() {
        return BusinessStatus.assertBespeakSuccess(this.status);
    }

    /**
     * 确信当前处于预约异常中
     *
     * @return boolean
     */
    public boolean assertBespeakAlert() {
        return BusinessStatus.assertBespeakAlert(this.status);
    }

    /**
     * 确信当前处于预约异常已处理
     *
     * @return boolean
     */
    public boolean assertBespeakExceptionHandler() {
        return BusinessStatus.assertBespeakExceptionHandler(this.status);
    }

    /**
     * 确信当前处于预约取消
     *
     * @return boolean
     */
    public boolean assertBespeakCancel() {
        return BusinessStatus.assertBespeakCancel(this.status);
    }

    /**
     * 确信当前处于预约生效
     *
     * @return boolean
     */
    public boolean assertBespeakWork() {
        return BusinessStatus.assertBespeakWork(this.status);
    }


    /**
     * 确信当前处于抢单超时状态
     *
     * @return boolean
     */
    public boolean assertGrabBusinessTimeout(int code) {
        return BusinessStatus.assertGrabBusinessTimeout(this.status);
    }

    /**
     * 确信当前处于用户终止派单状态
     *
     * @return boolean
     */
    public boolean assertTerminationBusiness(int code) {
        return BusinessStatus.assertTerminationBusiness(this.status);
    }

    /**
     * 确信当前处于流单状态
     *
     * @return boolean
     */
    public boolean assertLossBusinessTimeout(int code) {
        return BusinessStatus.assertLossBusinessTimeout(this.status);
    }

    /**
     * 确信当前处于异常状态
     *
     * @return boolean
     */
    public boolean assertException() {
        return BusinessStatus.assertException(this.status);
    }


    /**
     * 是否可以下线
     */
    public boolean isAbleDown() {
        return !(assertBeginBusiness() || assertBusiness());
    }


    /**
     * 设置当前处于激活状态
     */
    public void setAbleActive() {
        this.status = BusinessStatus.ACTIVE.getCode();
    }

    /**
     * 设置当前处于开始状态
     */
    public void setAbleGrabBusiness() {
        this.status = BusinessStatus.GRAB_BUSINESS.getCode();
    }


    /**
     * 设置当前处于开始状态
     */
    public void setAbleBeginBusiness() {
        this.status = BusinessStatus.BEGIN_BUSINESS.getCode();
    }

    /**
     * 设置当前处于预约成功状态
     */
    public void setAbleBespeakSuccess() {
        this.status = BusinessStatus.BESPEAK_SUCCESS.getCode();
    }

    /**
     * 设置当前处于进行状态
     */
    public void setAbleBusiness() {
        this.status = BusinessStatus.BUSINESS.getCode();
    }

    /**
     * 设置当前处于进行状态
     */
    public void setAbleFinish() {
        this.status = BusinessStatus.FINISH.getCode();
    }

    /**
     * 设置当前处于取消状态
     */
    public void setAbleCancal() {
        this.status = BusinessStatus.CANCEL.getCode();
    }


    /**
     * 设置当前处于异常状态
     */
    public void setAbleException() {
        this.status = BusinessStatus.EXCEPTION.getCode();
    }


    /**
     * @author Anson
     * @date 17-3-30
     * @name 设置未支付
     * @since 1.0.3
     */
    public void setAbleUnPay() {
        this.setOrderStatus(OrderStatus.UNPAID_ORDER.getCode());
    }

    /**
     * 是否已经支付了
     */
    @Column(name = "order_status")
    private int orderStatus;

    /**
     * 当前订单id 且是1:1的关系
     */
    @Column(name = "order_id", unique = true)
    private String orderId;

    /**
     * 业务流水号 且是1:1的关系
     */
    @Column(name = "business_id", unique = true)
    @NotEmpty(message = "当前业务流水号不能为空")
    private String businessId;

    /**
     * 请求用户的id
     */
    @Column(name = "user_id")
    @NotEmpty(message = "请求用户的id不能为空")
    private String userId;

    /**
     * service_register_id
     */
    @Column(name = "service_register_id")
    @NotEmpty(message = "当前司机绑定车辆id不能为空")
    private String serviceRegisterId;


    /**
     * 车辆
     */
    @ManyToOne(targetEntity = DriverRegisterBusRelative.class, fetch = FetchType.EAGER)
    @JoinColumn(name = "service_register_id", insertable = false, updatable = false)
    @Fetch(FetchMode.JOIN)
    private DriverRegisterBusRelative driverRegisterBusRelative;

    /**
     * 司机id
     */
    @Column(name = "driver_id")
    @NotEmpty(message = "司机id不能为空")
    private String driverId;

    /**
     * 状态 ,20:开始;30:进行;40:完毕;50：取消;60:下线;-10:异常
     * 部分同{@link tt.dz.egobus.servicemanager.entities.DriverRegisterBusRelative.RelativeStatus}一样
     */
    @Column(length = 10)
    private int status;


    /**
     * 是否失效
     */
    @Column(name = "is_validate")
    private boolean isValidate;

    /**
     * 业务服务号
     */
    @Column(name = "business_code")
    private int businessCode;

    /**
     * 总价格
     */
    @Column(name = "service_fee", precision = 10, scale = 2)
    private double serviceFee;

    //--------------------新增字段 2017年08月25日16:14:28 --------------------------//

    /**
     * 用户请求类型
     * 1.及时请求派车
     * 2.预约请求派车
     */
    @Column(name = "request_type", nullable = false)
    @ColumnDefault(value = "1")
    private int requestType = UserRequestTypeInfo.UserRequestType.NOW.getCode();

    /**
     * 是否自己用车
     */
    @Column(name = "is_ride_self", nullable = false)
    @ColumnDefault(value = "true")
    private Boolean isRideSelf = true;

    /**
     * 当前行程是否超时了
     */
    @Column(name = "is_over_time", nullable = false)
    @ColumnDefault(value = "false")
    private Boolean isOverTime = false;


    public String getServiceRegisterId() {
        return serviceRegisterId;
    }

    public void setServiceRegisterId(String serviceRegisterId) {
        this.serviceRegisterId = serviceRegisterId;
    }

    public String getDriverId() {
        return driverId;
    }

    public void setDriverId(String driverId) {
        this.driverId = driverId;
    }

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public boolean getIsValidate() {
        return isValidate;
    }

    public void setIsValidate(boolean validate) {
        isValidate = validate;
    }

    public boolean isValidate() {
        return isValidate;
    }

    public void setValidate(boolean validate) {
        isValidate = validate;
    }

    public int getBusinessCode() {
        return businessCode;
    }

    public void setBusinessCode(int businessCode) {
        this.businessCode = businessCode;
    }

    public DriverRegisterBusRelative getDriverRegisterBusRelative() {
        return driverRegisterBusRelative;
    }

    public void setDriverRegisterBusRelative(DriverRegisterBusRelative driverRegisterBusRelative) {
        this.driverRegisterBusRelative = driverRegisterBusRelative;
    }

    public String getBusinessId() {
        return businessId;
    }

    public void setBusinessId(String businessId) {
        this.businessId = businessId;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public int getOrderStatus() {
        return orderStatus;
    }

    public void setOrderStatus(int orderStatus) {
        this.orderStatus = orderStatus;
    }

    public String getOrderId() {
        return orderId;
    }

    public void setOrderId(String orderId) {
        this.orderId = orderId;
    }

    public double getServiceFee() {
        return serviceFee;
    }

    public void setServiceFee(double serviceFee) {
        this.serviceFee = serviceFee;
    }

    public int getRequestType() {
        return requestType;
    }

    public void setRequestType(int requestType) {
        this.requestType = requestType;
    }

    public Boolean getRideSelf() {
        return isRideSelf;
    }

    public void setRideSelf(Boolean rideSelf) {
        isRideSelf = rideSelf;
    }

    public Boolean getIsRideSelf() {
        return isRideSelf;
    }

    public void setIsRideSelf(Boolean rideSelf) {
        isRideSelf = rideSelf;
    }

    public Boolean getOverTime() {
        return isOverTime;
    }

    public void setOverTime(Boolean overTime) {
        isOverTime = overTime;
    }

    public Boolean getIsOverTime() {
        return isOverTime;
    }

    public void setIsOverTime(Boolean overTime) {
        isOverTime = overTime;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof BusinessService)) return false;
        BusinessService that = (BusinessService) o;
        return this.hashCode() == that.hashCode();
    }


    @Override
    public int hashCode() {
        int result;
        long temp;
        result = getOrderStatus();
        result = 31 * result + (getOrderId() != null ? getOrderId().hashCode() : 0);
        result = 31 * result + (getBusinessId() != null ? getBusinessId().hashCode() : 0);
        result = 31 * result + (getUserId() != null ? getUserId().hashCode() : 0);
        result = 31 * result + (getServiceRegisterId() != null ? getServiceRegisterId().hashCode() : 0);
        result = 31 * result + (getDriverRegisterBusRelative() != null ? getDriverRegisterBusRelative().hashCode() : 0);
        result = 31 * result + (getDriverId() != null ? getDriverId().hashCode() : 0);
        result = 31 * result + getStatus();
        result = 31 * result + (isValidate() ? 1 : 0);
        result = 31 * result + getBusinessCode();
        temp = Double.doubleToLongBits(getServiceFee());
        result = 31 * result + (int) (temp ^ (temp >>> 32));
        result = 31 * result + getRequestType();
        result = 31 * result + (isRideSelf != null ? isRideSelf.hashCode() : 0);
        result = 31 * result + (isOverTime != null ? isOverTime.hashCode() : 0);
        return result;
    }

    @Override
    public String toString() {
        return "BusinessService{" +
                "orderStatus=" + orderStatus +
                ", orderId='" + orderId + '\'' +
                ", businessId='" + businessId + '\'' +
                ", userId='" + userId + '\'' +
                ", serviceRegisterId='" + serviceRegisterId + '\'' +
                ", driverRegisterBusRelative=" + driverRegisterBusRelative +
                ", driverId='" + driverId + '\'' +
                ", status=" + status +
                ", isValidate=" + isValidate +
                ", businessCode=" + businessCode +
                ", serviceFee=" + serviceFee +
                ", requestType=" + requestType +
                ", isRideSelf=" + isRideSelf +
                ", isOverTime=" + isOverTime +
                '}';
    }
}
